#include "../../bootloader/linkage.h"

.balign 0x1000

.text
.code16

ENTRY(_APU_BOOT_START)
_APU_BOOT_BASE = . #绝对地址
    cli
    wbinvd

    mov %cs,%ax
    mov %ax,%ds
    mov %ax,%es
    mov %ax,%ss
    mov %ax,%fs
    mov %ax,%gs


    movl $(_APU_BOOT_TEMP_STACK_END - _APU_BOOT_BASE),%esp

#get base address
    mov %cs,%ax
    movzx %ax,%esi
    shll $4,%esi
    
#set gdt and 32&64 code address

    leal (_APU_CODE32 -_APU_BOOT_BASE)(%esi),%eax
    movl %eax,_APU_CODE32_VECTOR - _APU_BOOT_BASE

    leal (_APU_CODE64 -_APU_BOOT_BASE)(%esi),%eax
    movl %eax,_APU_CODE64_VECTOR - _APU_BOOT_BASE

    leal (_APU_TMP_GDT -_APU_BOOT_BASE)(%esi),%eax
    movl %eax,_APU_TMP_GDT + 2 - _APU_BOOT_BASE



#load idt gdt
    lidtl _APU_TMP_IDT - _APU_BOOT_BASE
    lgdtl _APU_TMP_GDT - _APU_BOOT_BASE

#enable protected mode
    smsw %ax
    bts $0,%ax
    lmsw %ax

#go to 32 code
    ljmpl *(_APU_CODE32_VECTOR - _APU_BOOT_BASE)  #必须加l,不然就是使用16位堆栈


.code32
.balign 4
_APU_CODE32:

	mov	$0x10,	%ax
	mov	%ax,	%ds
	mov	%ax,	%es
	mov	%ax,	%ss
	mov	%ax,	%fs
	mov	%ax,	%gs

	leal	(_APU_BOOT_TEMP_STACK_END - _APU_BOOT_BASE)(%esi),	%eax
	movl	%eax,	%esp

# open PAE

    movl	%cr4,	%eax
	bts	$5,	%eax
	movl	%eax,	%cr4
# set page table

	movl	$0x90000,	%eax
	movl	%eax,	%cr3
	
#	enable long mode

	movl	$0xC0000080,	%ecx
	rdmsr

	bts	$8,	%eax
	wrmsr

#	enable PE & paging

	movl	%cr0,	%eax
	bts	$0,	%eax
	bts	$31,	%eax
	movl	%eax,	%cr0
	
	ljmpl	*(_APU_CODE64_VECTOR - _APU_BOOT_BASE)(%esi)

.code64
.balign 4
_APU_CODE64:

	movq	$0x20,	%rax
	movq	%rax,	%ds
	movq	%rax,	%es
	movq	%rax,	%fs
	movq	%rax,	%gs
	movq	%rax,	%ss

	movq 	$0xffff800000100000, %rax
	jmpq 	*%rax
	hlt


.balign 4
_APU_TMP_IDT:
    .word 0
    .word 0,0


.balign 4
_APU_TMP_GDT:
    .short	_APU_TMP_GDT_END - _APU_TMP_GDT
	.long	_APU_TMP_GDT - _APU_BOOT_BASE
	.short	0
	.quad	0x00cf9a000000ffff
	.quad	0x00cf92000000ffff
	.quad	0x0020980000000000
	.quad	0x0000920000000000



_APU_TMP_GDT_END:



.balign 4
_APU_CODE32_VECTOR:
    .long _APU_CODE32 - _APU_BOOT_BASE
    .word 0x08,0

.balign 4
_APU_CODE64_VECTOR:
	.long	_APU_CODE64 - _APU_BOOT_BASE
	.word	0x18,0	

_APU_BOOT_TEMP_STACK:
    .org 0x400
_APU_BOOT_TEMP_STACK_END:

ENTRY(_APU_BOOT_END)

